package com.tubruk.trackme;

import java.util.ArrayList;
import java.util.List;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.MyLocationOverlay;
import com.google.android.maps.Overlay;
import com.google.android.maps.OverlayItem;
import com.tubruk.database.DatabaseHelper;
import com.tubruk.database.OptionDB;

import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.location.LocationProvider;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;

public class MyLocationListener implements LocationListener {

	private MyGeoPoint previousPoint;

	private LocationManager myManager;
	private MapController mapController;

	private List<Overlay> mapOverlays;

	private Resources resources;

	private MyItemizedOverlay itemizedoverlay;
	private MyLocationOverlay myLocOverlay;
	
	private static Double latitude;
	private static Double longitude;
	
	private Boolean started = false;
	private Boolean allowed = false;
	
	private List<MyGeoPoint> myGeoPoints;
	
	private MyRouteOverlay routeOverlay;
	
	private MapView mapView;
	
	
	public MyLocationListener(Resources resources, LocationManager manager,
			MapController mapController, List<Overlay> mapOverlays, MyLocationOverlay myLocOverlay, MapView mapView) {
		this.myManager = manager;
		this.mapController = mapController;
		this.resources = resources;
		this.mapOverlays = mapOverlays;
		this.myLocOverlay = myLocOverlay;
		myGeoPoints = new ArrayList<MyGeoPoint>();
		routeOverlay = new MyRouteOverlay(myGeoPoints);

		this.mapView = mapView;
		
		Drawable drawable = resources.getDrawable(R.drawable.androidmarker);
		itemizedoverlay = new MyItemizedOverlay(drawable, TrackMapActivity.getContext());
		
		previousPoint = null;
		
		mapOverlays.clear();
		mapOverlays.add(routeOverlay);
	}

	public void onLocationChanged(Location location) {
		if (started) {
			
			MyGeoPoint point = new MyGeoPoint(location);
			myGeoPoints.add(point);
			// we got new location info. lets display it in the textview
			String s = "";
			s += "Time:\t\t\t" + point.getTimeStart() + "\n";
			s += "Latitude:\t\t" + point.getLatitude() + "\n";
			s += "Longitude:\t\t" + point.getLongitude() + "\n";
			s += "Speed:\t\t" + point.getSpeed() + "\n";
			s += "Orientation:" + point.getOrientation() + "\n";
			//s += "\tAccuracy:  " + location.getAccuracy() + "\n";
			Log.d("LOCATION UPDATE: ", s);
			
			//get geo point and center the map
			//mapController.animateTo(point);
	
			//add new point to map overlay and draw it
			int mode = 1;
			if (previousPoint != null) {
				mode = 2;
			}
			routeOverlay.setMode(mode);
			//mapOverlays.clear();
			//mapOverlays.add(new MyRouteOverlay(myGeoPoints, mode));
			
			//routeOverlay.setPoints(myGeoPoints, mode);
			//mapView.postInvalidate();
			
			mapView.invalidate();
			
			Log.d("LISTENER", "mapOverlays.size(): " + mapOverlays.size());
			previousPoint = point;
		}
	}

	public void onProviderDisabled(String provider) {
		Toast.makeText(TrackMapActivity.getContext(), "Please enable GPS", Toast.LENGTH_LONG).show();
		allowed = false;
	}    

    public void onProviderEnabled(String provider) {
    	allowed = true;
    }    

    public void onStatusChanged(String provider, int status, Bundle extras) {
    	switch (status) {
    	case LocationProvider.AVAILABLE:
    		if (started) {
    			startListening();
    		}
    		allowed = true;
    		Toast.makeText(TrackMapActivity.getContext(), "GPS enabled", Toast.LENGTH_LONG).show();
    	case LocationProvider.OUT_OF_SERVICE:
    		Toast.makeText(TrackMapActivity.getContext(), "GPS Out of Service", Toast.LENGTH_LONG).show();
    	case LocationProvider.TEMPORARILY_UNAVAILABLE:
    		Toast.makeText(TrackMapActivity.getContext(), "GPS Temporary Unavailable", Toast.LENGTH_LONG).show();
    	}
    }

	public static double getLatitude() {
		return latitude;
	}

	public static double getLongitude() {
		return longitude;
	}

	/*
	 * @Override protected void onDestroy() { stopListening();
	 * super.onDestroy(); }
	 * 
	 * @Override protected void onPause() { stopListening(); super.onPause(); }
	 * 
	 * @Override protected void onResume() { startListening(); super.onResume();
	 * }
	 */

	/**********************************************************************
	 * helpers for starting/stopping monitoring of GPS changes below
	 **********************************************************************/
	public boolean startListening() {
		if (!started) { 
			//mapOverlays.clear();
			previousPoint = null;
			myGeoPoints.clear();
		}
		
		//mestinya preference nya diambil dari pilihan option menu di title bar
		int preference = Integer.parseInt(OptionDB.getValueById(DatabaseHelper.TABLE_CONSTANT.ID_PREFERENCE));
		
		int distance = 0;
		long time = 0;
		if (preference == DatabaseHelper.TABLE_CONSTANT_LIST.ID_PREFERENCE_WALK){
			distance = Integer.parseInt(OptionDB.getValueById(DatabaseHelper.TABLE_CONSTANT.ID_WALK_DISTANCE));
			time = Long.parseLong(OptionDB.getValueById(DatabaseHelper.TABLE_CONSTANT.ID_WALK_TIME));
		}else if (preference == DatabaseHelper.TABLE_CONSTANT_LIST.ID_PREFERENCE_BIKE){
			distance = Integer.parseInt(OptionDB.getValueById(DatabaseHelper.TABLE_CONSTANT.ID_BIKE_DISTANCE));
			time = Long.parseLong(OptionDB.getValueById(DatabaseHelper.TABLE_CONSTANT.ID_BIKE_TIME));
		}else {
			//car
			distance = Integer.parseInt(OptionDB.getValueById(DatabaseHelper.TABLE_CONSTANT.ID_DRIVE_DISTANCE));
			time = Long.parseLong(OptionDB.getValueById(DatabaseHelper.TABLE_CONSTANT.ID_DRIVE_TIME));
		}
		
		time = time * 1000;
		
		myManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, time, distance, this);
		if (myManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
			started = true;
		} else {
			Toast.makeText(TrackMapActivity.getContext(), "Please enable GPS", Toast.LENGTH_LONG).show();
		}
		return started;
	}

	public void stopListening() {
		if (started) {
			if (!mapOverlays.isEmpty()) {
				/*
				previousPoint = myGeoPoints.get(myGeoPoints.size() - 1);
				myGeoPoints.remove(myGeoPoints.size() - 1);
				myGeoPoints.add(previousPoint);
				mapController.animateTo(previousPoint);
				
				mapOverlays.clear();
				mapOverlays.add(new MyRouteOverlay(myGeoPoints, 3));
				*/
				routeOverlay.setMode(3);
				mapView.invalidate();
			}
			
			if (myManager != null) {
				myManager.removeUpdates(this);
			}
			
			started = false;
		}
	}

	public List<Overlay> getMapOverlays() {
		return mapOverlays;
	}
	
	public List<MyGeoPoint> getMyGeopoints() {
		return myGeoPoints;
	}

}
